
#include "Common/ReliveMgr/ReliveMgr.h"
#include "Common/TableData/PkmodePkWantedCfg.h"
#include "Common/TableDataEx/PkModeCfg.h"
#include "Common/TableData/ConstantConstantCfg.h"
#include "Common/TableData/MapMapCfg.h"
#include "Common/TableDataEx/MapCfg.h"
#include "Common/TableData/TeleportBornCfg.h"
#include "Common/ComDefine.pb.h"
#include "base/core/gamemath.h"
ReliveMgr::ReliveMgr()
{

}

ReliveMgr::~ReliveMgr()
{

}

bool ReliveMgr::Init()
{
	return true;
}

void ReliveMgr::UnInit()
{

}

//获取杀戮惩罚的坐标和地图
bool ReliveMgr::GetBanishReliveInfo(uint32_t curMapId, uint32_t curSceneId, Point3<float> curPos, int32_t camp, uint32_t pkValue, uint32_t &reliveMapId, uint32_t &reliveSceneId, Point3<float> &relivePos)
{
	//找到流放之地地图
	const ConstantConstantCfgInfo *pJailMapID = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_ClearPoint_Jail);
	if (nullptr == pJailMapID)
	{
		LogErrFmtPrint("ReliveMgr::GetBanishReliveInfo.....nullptr == pJailMapID, id:%d ", EArg_ClearPoint_Jail);
		return false;
	}
	//通辑等级上限(严格按照 C级 B级 A级 S级 SSS级 的顺序)，根据这个值来区分该玩家所属的PK等级
	VEC_UINT32 vecPkRedLineLimit;
	vecPkRedLineLimit.clear();
	g_GetPkModeCfgMgr()->GetPkLvLimit(vecPkRedLineLimit);
	if (vecPkRedLineLimit.size() < 2)
	{
		LogErrFmtPrint("ReliveMgr::GetBanishReliveInfo.....vecPkRedLineLimit.size() < 2 ");
		return false;
	}
	reliveMapId = pJailMapID->constantdata;
	reliveSceneId = pJailMapID->constantdata;
	const MapMapCfgInfo *pMapCfgInfo = g_GetMapMapCfgTable()->GetMapMapCfgInfo(reliveMapId);
	if (nullptr == pMapCfgInfo)
	{
		LogErrFmtPrint("ReliveMgr::GetBanishReliveInfo.....nullptr == pMapCfgInfo curMapId:%u,camp:%d, reliveMapId:%u ", curMapId,camp, reliveMapId);
		return false;
	}
	if (pkValue < vecPkRedLineLimit[1] /*|| curMapId == reliveMapId*/) //已经再这个地图的也需要复活坐标
	{
		//小于A级的，不用在这惩罚
		return false;
	}

	//获取复活地图的复活坐标
	relivePos = GetMapRelivePos(reliveMapId, curPos, camp);
	if (relivePos.length() <= 0)
	{
		LogErrFmtPrint("ReliveMgr::GetBanishReliveInfo.....elievePos.length() <= 0 curMapId:%u,camp:%d,curPos:%f,%f,%f, reliveMapId:%u ", curMapId,camp,curPos.x,curPos.y,curPos.z, reliveMapId);
		return false;
	}
	//复活的父地图必须是非动态地图
	if (g_GetMapCfgMgr()->IsDynamic(reliveMapId))
	{
		LogErrFmtPrint("ReliveMgr::GetBanishReliveInfo.....elievePos.length() <= 0 curMapId:%u,camp:%d,curPos:%f,%f,%f, reliveMapId:%u ", curMapId, camp, curPos.x, curPos.y, curPos.z, reliveMapId);
		return false;
	}

	return true;
}

//死亡复活地图ID
bool ReliveMgr::GetDeadReliveInfo(uint32_t curMapId, uint32_t curSceneId, Point3<float> curPos, int32_t camp, uint32_t &reliveMapId, uint32_t &reliveSceneId, Point3<float> &relivePos)
{
	reliveMapId = curMapId;
	reliveSceneId = curSceneId;
	//死亡复活先找他父地图，有直接复活在他父地图中
	const MapMapCfgInfo * pMapCfg = g_GetMapMapCfgTable()->GetMapMapCfgInfo(curMapId);
	if (nullptr != pMapCfg)
	{
		uint32_t parentMapId = CommonApi::StrToInt(pMapCfg->parentMap);
		//校验下父地图是否存在,如果不存在 直接找默认的地图复活
		const MapMapCfgInfo * pParentMapCfg = g_GetMapMapCfgTable()->GetMapMapCfgInfo(parentMapId);
		if (nullptr == pParentMapCfg)
		{
			if (!g_GetMapCfgMgr()->IsDynamic(curMapId)) //这里要判断下动态地图，主要是为了区分副本复活
			{
				relivePos = GetMapRelivePos(reliveMapId, curPos, camp);
				if (relivePos.length() <= 0)
				{
					const ConstantConstantCfgInfo *pConstCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_Relive_Default_MapID);
					if (nullptr == pConstCfg)
					{
						LogErrFmtPrint("ReliveMgr::GetDeadReliveInfo...nullptr == pConstCfg...curMapId:%u ,id:%d，parentMapId:%u ", curMapId, EArg_Relive_Default_MapID, parentMapId);
						return false;
					}
					//校验默认地图
					const MapMapCfgInfo * pDefaultMapCfg = g_GetMapMapCfgTable()->GetMapMapCfgInfo(pConstCfg->constantdata);
					if (nullptr == pDefaultMapCfg)
					{
						LogErrFmtPrint("ReliveMgr::GetDeadReliveInfo...nullptr == pDefaultMapCfg...curMapId:%u ,id:%d,mapid:%u ", curMapId, EArg_Relive_Default_MapID, pConstCfg->constantdata);
						return false;
					}
					reliveMapId = pDefaultMapCfg->mapId;
					reliveSceneId = pDefaultMapCfg->mapId;
					//复活的父地图必须是非动态地图
					if (g_GetMapCfgMgr()->IsDynamic(reliveMapId))
					{
						LogErrFmtPrint("ReliveMgr::GetDeadReliveInfo...reliveMapId is dynamic map...curMapId:%u ,curscene:%u,reliveMapId:%u,relivescene:%u ", curMapId, curSceneId, reliveMapId, reliveSceneId);
						return false;
					}
				}
				else
				{
					return true;
				}
			}
			else
			{
				//动态场景复活，在当前场景
			}
		}
		else
		{
			reliveMapId = pParentMapCfg->mapId;
			reliveSceneId = pParentMapCfg->mapId;
			//复活的父地图必须是非动态地图
			if (g_GetMapCfgMgr()->IsDynamic(reliveMapId))
			{
				LogErrFmtPrint("ReliveMgr::GetDeadReliveInfo...reliveMapId is dynamic map...curMapId:%u ,curscene:%u,reliveMapId:%u,relivescene:%u ", curMapId, curSceneId, reliveMapId, reliveSceneId);
				return false;
			}
		}
	}
	//获取复活地图的复活坐标
	relivePos = GetMapRelivePos(reliveMapId, curPos, camp);
	if (relivePos.length() <= 0)
	{
		LogErrFmtPrint("ReliveMgr::GetDeadReliveInfo.....relivePos.length() <= 0 curMapId:%u,curscene:%u, camp:%d,curPos:%f,%f,%f, reliveMapId:%u,relivescene:%u ", curMapId,curSceneId, camp, curPos.x, curPos.y, curPos.z, reliveMapId,reliveSceneId);
		return false;
	}

	return true;
}

//获取复活信息
bool ReliveMgr::GetDeadReliveInfoEx(uint32_t curMapId, uint32_t curSceneId, Point3<float> curPos, int32_t camp, uint32_t pkValue, uint32_t &reliveMapId, uint32_t &reliveSceneId, Point3<float> &relivePos)
{
	if (GetBanishReliveInfo(curMapId, curSceneId,curPos, camp, pkValue, reliveMapId, reliveSceneId, relivePos))
	{
		return true;
	}
	return GetDeadReliveInfo(curMapId, curSceneId, curPos, camp, reliveMapId, reliveSceneId, relivePos);
}

//获取地图复活点坐标 reliveMapId:复活地图ID,curPos:角色当前的坐标，camp：阵营
Point3<float> ReliveMgr::GetMapRelivePos(uint32_t reliveMapId, Point3<float> curPos, int32_t camp)
{
	uint32_t minCampDistance = 100000000;
	uint32_t minNoCampDistance = 100000000;
	Point3<float> nearCampPos = Point3<float>(0.0, 0.0, 0.0);
	Point3<float> nearNoCampPos = Point3<float>(0.0, 0.0, 0.0);
	//先找到该图出身点信息
	const VecBornPosCfg *pVecBornCfg = g_GetMapCfgMgr()->GetBornCfgByMap(reliveMapId);
	if (nullptr == pVecBornCfg)
	{
		return nearCampPos;
	}
	VecBornPosCfg::const_iterator iter = pVecBornCfg->begin();
	for (; iter != pVecBornCfg->end(); ++iter)
	{
		const SBornPosCfgInfo &info = (*iter);
		const TeleportBornCfgInfo * pBornConfig = g_GetTeleportBornCfgTable()->GetTeleportBornCfgInfo(info.bornId);
		if (nullptr == pBornConfig)
		{
			continue;
		}
		//当前阵营的出生点
		if (pBornConfig->camp == camp)
		{
			uint32_t distance = (uint32_t)point3Length(curPos, info.bornpos);
			if (distance < minCampDistance)
			{
				nearCampPos = info.bornpos;
			}
		}
		//中立阵营的出生点
		if (0 == pBornConfig->camp)
		{
			uint32_t distance = (uint32_t)point3Length(curPos, info.bornpos);
			if (distance < minNoCampDistance)
			{
				nearNoCampPos = info.bornpos;
			}
		}
	}
	//如果没找到当前阵营的复活点，直接取中立阵营的出生点
	if (nearCampPos.length() <= 0)
	{
		nearCampPos = nearNoCampPos;
	}

	return nearCampPos;
}